package ws

import (
	"encoding/json"
	"fmt"
	"github.com/gorilla/websocket"
	"iron_man_comm/src/common/log"
	"iron_man_comm/src/ros_bag/cmd"
	"net/http"
)

var upgrader = websocket.Upgrader{
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
	CheckOrigin:     func(r *http.Request) bool { return true },
}

type WsManager struct {
	conn    *websocket.Conn
	CmdChan *chan cmd.CmdType
}

func (ws *WsManager) Start(port int) error {
	http.HandleFunc("/ws", ws.wsHandler)
	err := http.ListenAndServe(fmt.Sprintf(":%d", port), nil)
	if nil != err {
		log.Error("ws listen fail, port: %d, err: %s", port, err.Error())
		return err
	}
	log.Info("ws start listen, port: %d", port)
	return nil
}

func (ws *WsManager) SendMsg(msg interface{}) {
	err := ws.conn.WriteJSON(msg)
	if err != nil {
		log.Error("ws send fail, err: %s", err.Error())
		return
	}
}

func (ws *WsManager) wsHandler(w http.ResponseWriter, r *http.Request) {
	hostAddress := r.RemoteAddr
	log.Info("new client connected, host: %s", hostAddress)
	// 将HTTP连接升级为WebSocket连接
	var err error
	ws.conn, err = upgrader.Upgrade(w, r, nil)
	if err != nil {
		return
	}
	defer ws.conn.Close()

	for {
		// 读取消息
		messageType, message, err := ws.conn.ReadMessage()
		if err != nil {
			ws.conn = nil
			log.Error("read msg error: %s", err.Error())
			break
		}
		log.Info("recv: %s", string(message))
		if websocket.TextMessage == messageType {
			ws.processWSData(message)
		}
	}
	log.Info("done, host: %s", hostAddress)
}
func (ws *WsManager) processWSData(message []byte) {
	var packageData PackageMsg
	err := json.Unmarshal(message, &packageData)
	if err != nil {
		log.Error("ws data unmarshal fail, err: %s, msg: %s", err.Error(), string(message))
		return
	}
	if packageData.Cmd == "parse" {
		ws.processParseData(packageData, message)
	}
}

func (ws *WsManager) processParseData(data PackageMsg, message []byte) {
	if data.Type == "start" {
		var parseMsg ParsePackage
		err := json.Unmarshal(message, &parseMsg)
		if err != nil {
			log.Error("process parse msg fail, err: %s, msg: %s", err.Error(), string(message))
			return
		}
		log.Info("process parse msg, %v", parseMsg)
		*ws.CmdChan <- cmd.CmdType{
			Cmd:   "start",
			Value: parseMsg.Data.Bag,
		}
	}
}
